package utils

import (
	"database/sql"
	"fmt"
)

// MysqlTable Mysql数据表
type MysqlTable struct {
	Conn *Mysql
	Name string
	PK   string
}

// NewMysqlTable 实例化数据表
func NewMysqlTable(mysql *Mysql, tableName, primaryKey string) (*MysqlTable, error) {
	if mysql == nil || tableName == "" {
		return nil, fmt.Errorf("wrong mysql connection or empty table name")
	}
	if primaryKey == "" {
		primaryKey = "id"
	}
	return &MysqlTable{
		Conn: mysql,
		Name: tableName,
		PK:   primaryKey,
	}, nil
}

// Truncate 清空表
func (mt *MysqlTable) Truncate() error {
	return mt.Conn.Truncate(mt.Name)
}

// InsertDuplicate 唯一索引约束，不存在则新增，存在则更新
func (mt *MysqlTable) InsertDuplicate(row *MysqlRow) (int64, error) {
	return mt.Conn.InsertDuplicate(mt.Name, row)
}

// InsertIgnore 唯一索引约束，存在则忽略
func (mt *MysqlTable) InsertIgnore(row *MysqlRow) (int64, error) {
	return mt.Conn.InsertIgnore(mt.Name, row)
}

// InsertReplace 唯一索引约束，不存在则新增，存在则先删再增
func (mt *MysqlTable) InsertReplace(row *MysqlRow) (int64, error) {
	return mt.Conn.InsertReplace(mt.Name, row)
}

// InsertBatch 批量插入
func (mt *MysqlTable) InsertBatch(rows []*MysqlRow) (int64, error) {
	return mt.Conn.InsertBatch(mt.Name, rows)
}

// Insert 插入新记录
func (mt *MysqlTable) Insert(row *MysqlRow) (int64, error) {
	return mt.Conn.Insert(mt.Name, row)
}

// Select 查询
func (mt *MysqlTable) Select(query string, params ...interface{}) ([]*MysqlRow, error) {
	return mt.Conn.Select(query, params...)
}

// SelPage 按页查询
func (mt *MysqlTable) SelPage(fn func(row *MysqlRow) error, page, numPerPage int64, queryWhere, queryOrder, selCols string, params ...interface{}) (int64, int64, int64, error) {
	return mt.Conn.SelPage(page, numPerPage, mt.Name, queryWhere, queryOrder, selCols, fn, params...)
}

// SelWalk 查询，每条记录执行指定函数
func (mt *MysqlTable) SelWalk(fn func(row *MysqlRow) error, query string, params ...interface{}) error {
	return mt.Conn.SelWalk(fn, query, params...)
}

// GetOne 按主键查询一条
func (mt *MysqlTable) GetOne(id string, cols ...string) (*MysqlRow, error) {
	return mt.Conn.GetOne(mt.Name, mt.PK, id, cols...)
}

// IdsWalk 按主键查询多条，并执行指定函数
func (mt *MysqlTable) IdsWalk(fn func(row *MysqlRow) error, ids []interface{}, cols ...string) error {
	return mt.Conn.IdsWalk(fn, mt.Name, mt.PK, ids, cols...)
}

// GetByIds 批量按主键查询
func (mt *MysqlTable) GetByIds(ids []interface{}, cols ...string) ([]*MysqlRow, error) {
	return mt.Conn.GetByIds(mt.Name, mt.PK, ids, cols...)
}

// Count 查询数据行数
func (mt *MysqlTable) Count(query string, params ...interface{}) (int64, error) {
	return mt.Conn.Count(query, params...)
}

// Update 更新数据
func (mt *MysqlTable) Update(query string, params ...interface{}) (int64, error) {
	return mt.Conn.Update(query, params...)
}

// UpdateById 按主键更新
func (mt *MysqlTable) UpdateById(row *MysqlRow, id string) (int64, error) {
	return mt.Conn.UpdateById(mt.Name, row, mt.PK, id)
}

// Delete 删除数据
func (mt *MysqlTable) Delete(query string, params ...interface{}) (int64, error) {
	return mt.Conn.Delete(query, params...)
}

// DelByIds 按主键删除一条或多条
func (mt *MysqlTable) DelByIds(ids ...interface{}) (int64, error) {
	return mt.Conn.DelByIds(mt.Name, mt.PK, ids...)
}

// Transaction 事务操作
func (mt *MysqlTable) Transaction(fn func(tx *sql.Tx, addLog func(query string, params []interface{}, err error)) error, opts *sql.TxOptions) error {
	return mt.Conn.Transaction(fn, opts)
}
